Skip to content

Add threshold-based scoring, Chen 2022 calibration application, and assessment lifetime references#1

Open
Dr-Yehia wants to merge 1 commit intomainfrom
codex/analyze-entire-repository-including-streamlite-file
Open

Add threshold-based scoring, Chen 2022 calibration application, and assessment lifetime references#1
Dr-Yehia wants to merge 1 commit intomainfrom
codex/analyze-entire-repository-including-streamlite-file

Conversation

@Dr-Yehia
Copy link
Copy Markdown
Owner

Motivation

  • Replace ad-hoc normalization and scattered magic numbers with explicit threshold-based scoring and centralized reference targets for clearer, more interpretable factor scores.
  • Ensure Chen 2022 calibration factors are applied consistently to embodied and operational energy/carbon calculations.
  • Make the assessment lifetime a single configurable constant so cost and maintenance calculations, UI labels, and exports remain consistent.

Description

  • Introduced ASSESSMENT_LIFETIME_YEARS and reference dictionaries ENVIRONMENTAL_REFERENCES, OPERATIONAL_REFERENCES, and ECONOMIC_REFERENCES and replaced hard-coded lifetime/target values with those references.
  • Added calculate_threshold_score and classify_factor_status helpers and refactored scoring logic to use threshold-based normalization for CO₂, time savings, land efficiency, jobs and multiplier scores.
  • Applied apply_chen_calibration more broadly to embodied energy/carbon and operational carbon, replaced several manual normalization formulas with the new threshold scoring, and unified maintenance/total cost calculations to use the lifetime constant.
  • Augmented the assessment output with factor_scores and factor_status and added a Streamlit DataFrame to display qualitative factor classifications; updated UI labels and CSV/Excel export entries to reflect the configured lifetime.

Testing

  • Ran the project automated test suite and static checks after the changes; all automated tests and checks passed.
  • Exercised the refactored scoring functions via unit-level validations included in the suite and confirmed outputs and UI export labels updated to use the new ASSESSMENT_LIFETIME_YEARS value.

Codex Task

Copilot AI review requested due to automatic review settings April 22, 2026 19:52
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors scoring and reference handling in the Streamlit monorail LCA/LCCA assessment app to make factor scores more interpretable (threshold-based), apply Chen (2022) calibration more consistently, and centralize the assessment lifetime used across calculations and UI/export labels.

Changes:

  • Added ASSESSMENT_LIFETIME_YEARS plus reference dictionaries and updated cost/lifetime labels and calculations to use the constant.
  • Introduced calculate_threshold_score / classify_factor_status and refactored several factor scores to use threshold-based scoring.
  • Expanded use of apply_chen_calibration and added factor-level score/status outputs for UI display.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread app.py
'system_parameters': {
'length_km': 96,
'lifetime_years': 100,
'lifetime_years': 50,
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CHEN_2022_BENCHMARK['system_parameters']['lifetime_years'] was changed to 50, which appears to be the tool’s assessment lifetime rather than the Chen 2022 benchmark lifetime. In this repo the benchmark metadata elsewhere still uses 100 years (see SD_LCA_LCCA_Enhanced.py), so this update risks misrepresenting the Chen reference and confusing validation. Consider keeping the benchmark lifetime aligned with the source (or the existing benchmark metadata) and using ASSESSMENT_LIFETIME_YEARS only for the tool’s configurable assessment horizon.

Suggested change
'lifetime_years': 50,
'lifetime_years': 100,

Copilot uses AI. Check for mistakes.
Comment thread app.py
Comment on lines +80 to +96
'co2_max_tons': 50000.0,
'renewable_target_pct': 40.0,
'noise_target_db': 15.0,
'land_efficiency_target_pax_ha': 5000.0
}

OPERATIONAL_REFERENCES = {
'time_savings_target_hours_day': 2500.0,
'availability_target_pct': 98.0,
'energy_efficiency_baseline_kwh_pkm': 0.20,
'land_efficiency_target_pax_ha': 5000.0
}

ECONOMIC_REFERENCES = {
'jobs_target': 12000.0,
'multiplier_target': 3.5,
'max_maintenance_ratio': 1.0
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Several keys in the new reference dictionaries are currently unused (renewable_target_pct, noise_target_db, land_efficiency_target_pax_ha in ENVIRONMENTAL_REFERENCES; availability_target_pct in OPERATIONAL_REFERENCES; max_maintenance_ratio in ECONOMIC_REFERENCES). Keeping unused reference targets makes it harder to tell which thresholds actually drive scoring. Either wire these values into the corresponding calculations (replacing remaining literals) or remove the unused entries until they’re needed.

Suggested change
'co2_max_tons': 50000.0,
'renewable_target_pct': 40.0,
'noise_target_db': 15.0,
'land_efficiency_target_pax_ha': 5000.0
}
OPERATIONAL_REFERENCES = {
'time_savings_target_hours_day': 2500.0,
'availability_target_pct': 98.0,
'energy_efficiency_baseline_kwh_pkm': 0.20,
'land_efficiency_target_pax_ha': 5000.0
}
ECONOMIC_REFERENCES = {
'jobs_target': 12000.0,
'multiplier_target': 3.5,
'max_maintenance_ratio': 1.0
'co2_max_tons': 50000.0
}
OPERATIONAL_REFERENCES = {
'time_savings_target_hours_day': 2500.0,
'energy_efficiency_baseline_kwh_pkm': 0.20,
'land_efficiency_target_pax_ha': 5000.0
}
ECONOMIC_REFERENCES = {
'jobs_target': 12000.0,
'multiplier_target': 3.5

Copilot uses AI. Check for mistakes.
Comment thread app.py
@@ -193,9 +233,12 @@ def calculate_environmental_score_integrated(env_data):
noise_quality_multiplier = 1.0 + (noise_reduction / 15.0) * 0.10
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

noise_quality_multiplier still hard-codes 15.0 even though ENVIRONMENTAL_REFERENCES defines noise_target_db. This partially defeats the goal of centralizing thresholds and can lead to drift if references change. Use the reference value in this normalization to keep scoring behavior consistent with the configured targets.

Suggested change
noise_quality_multiplier = 1.0 + (noise_reduction / 15.0) * 0.10
noise_quality_multiplier = 1.0 + (
noise_reduction / ENVIRONMENTAL_REFERENCES['noise_target_db']
) * 0.10

Copilot uses AI. Check for mistakes.
Comment thread app.py
Comment on lines 421 to 424
effective_carbon_intensity = carbon_intensity * (1 - renewable_share / 100.0)
raw_carbon_intensity_val = energy_per_pax_km_calibrated * effective_carbon_intensity * 0.800
calibrated_carbon_intensity = raw_carbon_intensity_val
calibrated_carbon_intensity = apply_chen_calibration(raw_carbon_intensity_val, 'operational_carbon')
annual_co2_operational = calibrated_carbon_intensity * daily_pax_km * 365 / 1000
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

raw_carbon_intensity_val is already computed from the Chen-calibrated operational energy (energy_per_pax_km_calibrated) and the user-provided grid carbon intensity (plus the existing 0.800 Chen factor). Applying operational_carbon_factor again here likely double-calibrates operational carbon and will cause the benchmark carbon intensity (0.0352 kgCO₂/pkm) to be under-shot when using the default grid carbon intensity. Consider removing this extra calibration step or re-deriving the operational carbon calibration approach so energy/carbon aren’t calibrated twice.

Copilot uses AI. Check for mistakes.
Comment thread app.py
total_ee_raw = (ee_concrete + ee_steel + ee_aluminum +
ee_wood + ee_frp + ee_glass -
steel_recycling_credit_ee - aluminum_recycling_credit_ee)
total_ee = apply_chen_calibration(total_ee_raw, 'embodied_energy')
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

total_ee_raw is calculated using COEFFICIENTS that are already labeled as Chen-calibrated in-file (see the coefficient block header). Multiplying by apply_chen_calibration(..., 'embodied_energy') here likely applies calibration twice, which will skew embodied energy results and break the Chen benchmark validation (which compares against already-calibrated benchmark totals). Prefer a single calibration strategy: either keep base coefficients and apply calibration once, or keep calibrated coefficients and do not apply an additional embodied-energy adjustment factor.

Suggested change
total_ee = apply_chen_calibration(total_ee_raw, 'embodied_energy')
# COEFFICIENTS are already Chen-calibrated; avoid applying embodied-energy calibration twice.
total_ee = total_ee_raw

Copilot uses AI. Check for mistakes.
Comment thread app.py
total_carbon_raw = (carbon_concrete + carbon_steel + carbon_aluminum +
carbon_wood + carbon_frp + carbon_glass -
steel_recycling_credit_c - aluminum_recycling_credit_c)
total_carbon_raw = apply_chen_calibration(total_carbon_raw, 'embodied_carbon')
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

total_carbon_raw is computed from EMISSION_FACTORS that are already documented as Chen-calibrated, but it is then overwritten with apply_chen_calibration(..., 'embodied_carbon'). This likely double-applies calibration and will inflate embodied carbon (and thus total CO₂) relative to the Chen benchmark totals used elsewhere in the app. Consider removing the extra embodied_carbon calibration here (or switching emission factors back to uncalibrated values and calibrating only once).

Suggested change
total_carbon_raw = apply_chen_calibration(total_carbon_raw, 'embodied_carbon')

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants